﻿using KAsFrame.Common.Dto;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace KAsFrame.Common.Extensions
{
    public static class SqlExtensions
    {
        /// <summary>
        /// 通用插入扩展，无需在意使用雪花id或guid、自增id
        /// </summary>
        /// <typeparam name="T">实体类</typeparam>
        /// <typeparam name="TPrimaryKey">主键类型</typeparam>
        /// <param name="insertable"></param>
        /// <returns></returns>
        public static async Task<long> ExcutedReturnIdAsync<T, TPrimaryKey>(this IInsertable<T> insertable)
            where T : IEntity<TPrimaryKey>, new()
        {
            if (typeof(TPrimaryKey) == typeof(long))
                return await insertable.ExecuteReturnSnowflakeIdAsync();
            else
                return await insertable.ExecuteReturnBigIdentityAsync();
        }

        /// <summary>
        /// Where的未软删除版本
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <param name="queryable"></param>
        /// <param name="exp"></param>
        /// <returns></returns>
        /// <remarks>如果对象实现IDeleteEntity，则添加IsDeleted = false条件</remarks>
        public static ISugarQueryable<T1> WhereNotDelete<T1>(this ISugarQueryable<T1> queryable, Expression<Func<T1, bool>> exp)
          where T1 : class, new()
        {
            var baseExp = Expressionable.Create<T1>();
            baseExp.And(exp);
            if (typeof(T1).GetInterfaces().Any(x => x == typeof(IDeleteEntity)))
            {
                var p = typeof(T1).GetProperty("IsDeleted");
                Expression<Func<T1, bool>> delExp = t1 => !Convert.ToBoolean(p.GetValue(t1));
                baseExp.And(delExp);
            }
            return queryable.Where(baseExp.ToExpression());
        }

        /// <summary>
        /// Where的未软删除版本
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <param name="queryable"></param>
        /// <param name="exp"></param>
        /// <returns></returns>
        /// <remarks>如果对象实现IDeleteEntity，则添加IsDeleted = false条件</remarks>
        public static ISugarQueryable<T1, T2> WhereNotDelete<T1, T2>(this ISugarQueryable<T1, T2> queryable, Expression<Func<T1, T2, bool>> exp)
          where T1 : class, new()
          where T2 : class, new()
        {
            var baseExp = Expressionable.Create<T1, T2>();
            baseExp.And(exp);
            if (typeof(T1).GetInterfaces().Any(x => x == typeof(IDeleteEntity)))
            {
                var p = typeof(T1).GetProperty("IsDeleted");
                Expression<Func<T1, T2, bool>> delExp = (t1, t2) => !Convert.ToBoolean(p.GetValue(t1));
                baseExp.And(delExp);
            }
            if (typeof(T2).GetInterfaces().Any(x => x == typeof(IDeleteEntity)))
            {
                var p = typeof(T2).GetProperty("IsDeleted");
                Expression<Func<T1, T2, bool>> delExp = (t1, t2) => !Convert.ToBoolean(p.GetValue(t2));
                baseExp.And(delExp);
            }
            return queryable.Where(baseExp.ToExpression());
        }

        /// <summary>
        /// Where的未软删除版本
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <param name="queryable"></param>
        /// <param name="exp"></param>
        /// <returns></returns>
        /// <remarks>如果对象实现IDeleteEntity，则添加IsDeleted = false条件</remarks>
        public static ISugarQueryable<T1, T2, T3> WhereNotDelete<T1, T2, T3>
            (this ISugarQueryable<T1, T2, T3> queryable, Expression<Func<T1, T2, T3, bool>> exp)
          where T1 : class, new()
          where T2 : class, new()
          where T3 : class, new()
        {
            var baseExp = Expressionable.Create<T1, T2, T3>();
            baseExp.And(exp);
            if (typeof(T1).GetInterfaces().Any(x => x == typeof(IDeleteEntity)))
            {
                var p = typeof(T1).GetProperty("IsDeleted");
                Expression<Func<T1, T2, T3, bool>> delExp = (t1, t2, t3) => !Convert.ToBoolean(p.GetValue(t1));
                baseExp.And(delExp);
            }
            if (typeof(T2).GetInterfaces().Any(x => x == typeof(IDeleteEntity)))
            {
                var p = typeof(T2).GetProperty("IsDeleted");
                Expression<Func<T1, T2, T3, bool>> delExp = (t1, t2, t3) => !Convert.ToBoolean(p.GetValue(t2));
                baseExp.And(delExp);
            }
            if (typeof(T3).GetInterfaces().Any(x => x == typeof(IDeleteEntity)))
            {
                var p = typeof(T2).GetProperty("IsDeleted");
                Expression<Func<T1, T2, T3, bool>> delExp = (t1, t2, t3) => !Convert.ToBoolean(p.GetValue(t3));
                baseExp.And(delExp);
            }
            return queryable.Where(baseExp.ToExpression());
        }
    }
}
